#pragma once
#include "../logger.hpp"
#include "chat_session.hxx"
#include "chat_session-odb.hxx"
#include "chat_session_member.hxx"
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <memory>
#include <odb/database.hxx>
#include <odb/mysql/database.hxx>
#include <sstream>
#include <string>
#include <vector>

namespace shared {

namespace dal {

class ChatSessionDao;
using ChatSessionDaoPtr = std::shared_ptr<ChatSessionDao>;

class ChatSessionDao
{
    using query = odb::query<entity::ChatSession>;
    using result = odb::result<entity::ChatSession>;
public:
    ChatSessionDao(const std::shared_ptr<odb::mysql::database>& db) : db_(db) {}

    // 新增指定会话
    bool insert(entity::ChatSession& chatSession)
    {
        try {
            odb::transaction trans(db_->begin());
            db_->persist(chatSession);
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("向会话数据表新增会话({}-{}-{})失败: {}", 
                chatSession.sessionType(), chatSession.sessionId(), chatSession.sessionName(), e.what());
            return false;
        }
        return true;
    }
    // 删除指定会话
    bool remove(const std::string& sessionId)
    {
        try {
            odb::transaction trans(db_->begin());
            db_->erase_query<entity::ChatSession>(query::sessionId == sessionId);
            // 同时删除该会话的成员记录
            typedef odb::query<entity::ChatSessionMember> csmQuery;
            db_->erase_query<entity::ChatSessionMember>(csmQuery::sessionId == sessionId);
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("从会话数据表删除会话({})失败: {}", sessionId, e.what());
            return false;
        }
        return true;
    }
    // 根据单聊会话的两用户删除会话
    bool remove(const std::string& reqId, const std::string& recvId)
    {
        try {
            odb::transaction trans(db_->begin());
            typedef odb::query<entity::SingleChatSession> squery;
            auto ret(db_->query_one<entity::SingleChatSession>(
                squery::css::sessionType == entity::ChatSessionType::SINGLE &&
                squery::csm1::userId == reqId &&
                squery::csm2::userId == recvId
            ));
            // 同时删除该会话的成员记录
            db_->erase_query<entity::ChatSession>(query::sessionId == ret->chatSessionId);
            // 同时删除该会话的成员记录
            typedef odb::query<entity::ChatSessionMember> csmQuery;
            db_->erase_query<entity::ChatSessionMember>(csmQuery::sessionId == ret->chatSessionId);
            trans.commit();
        } catch (const std::exception& e) {
            LOG_ERROR("从会话表删除单聊会话({}-{})失败: {}", reqId, recvId, e.what());
            return false;
        }
        return true;
    }
    // 获取指定会话的信息
    entity::ChatSessionPtr selectOneSession(const std::string& sessionId)
    {
        entity::ChatSessionPtr res;
            try {
                odb::transaction trans(db_->begin());
                res.reset(db_->query_one<entity::ChatSession>(query::sessionId == sessionId));
                trans.commit();
            } catch (const std::exception& e) {
                LOG_ERROR("获取会话成员({})失败: {}", sessionId, e.what());
        }
        return res;
    }
    std::vector<entity::SingleChatSession> selectAllSingleSession(const std::string& userId)
    {
        std::vector<entity::SingleChatSession> res;
            try {
                odb::transaction trans(db_->begin());
                typedef odb::query<entity::SingleChatSession> query;
                typedef odb::result<entity::SingleChatSession> result;
                result ret(db_->query<entity::SingleChatSession>(
                    query::css::sessionType == entity::ChatSessionType::SINGLE &&
                    query::csm1::userId == userId &&
                    query::csm2::userId != userId
                ));
                for(auto it = ret.begin(); it != ret.end(); ++it) {
                    res.emplace_back(*it);
                }
                trans.commit();
            } catch (const std::exception& e) {
                LOG_ERROR("获取用户({})所有单聊会话失败: {}", userId, e.what());
        }
        return res;
    }  
    std::vector<entity::GroupChatSession> selectAllGroupSession(const std::string& userId)
    {
        std::vector<entity::GroupChatSession> res;
            try {
                odb::transaction trans(db_->begin());
                typedef odb::query<entity::GroupChatSession> query;
                typedef odb::result<entity::GroupChatSession> result;
                result ret(db_->query<entity::GroupChatSession>(
                    query::css::sessionType == entity::ChatSessionType::GROUP &&
                    query::csm::userId == userId
                ));
                for(auto it = ret.begin(); it != ret.end(); ++it) {
                    res.emplace_back(*it);
                }
                trans.commit();
            } catch (const std::exception& e) {
                LOG_ERROR("获取用户({})所有群聊会话失败: {}", userId, e.what());
        }
        return res;
    }
private:
    std::shared_ptr<odb::mysql::database> db_;
};


}}